package vnetlab.xml;

import com.sun.org.apache.xml.internal.serialize.OutputFormat;
import com.sun.org.apache.xml.internal.serialize.XMLSerializer;
import java.io.BufferedReader;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileWriter;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.io.StringReader;
import java.io.StringWriter;
import java.io.Writer;
import java.util.ArrayList;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.swing.JOptionPane;

import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;
import org.w3c.dom.Document;
import org.xml.sax.InputSource;
import org.xml.sax.SAXException;
import vnetlab.manager.Configuration;

public class XmlManager {
	 
    private static Document stringToDom(String xmlSource) throws SAXException, ParserConfigurationException, IOException {
        DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
        DocumentBuilder builder = factory.newDocumentBuilder();
        return builder.parse(new InputSource(new StringReader(xmlSource)));
    }

    /**
     *
     * Método que formata o texto XML para o mesmo ficar identado
     *
     * @param xmlSource
     * @return
     * @throws IOException
     * @throws ParserConfigurationException
     * @throws SAXException
     */
   public static String format(String xmlSource) throws IOException, ParserConfigurationException, SAXException {
        Document document = stringToDom(xmlSource);
        OutputFormat of = new OutputFormat();
        of.setIndent(2);
        of.setOmitXMLDeclaration(true);

        Writer writer = new StringWriter();
        XMLSerializer serializer = new XMLSerializer(writer, of);
        serializer.serialize(document);

        return writer.toString();
    }

   /**
    * Método que habilita ou desabilita o arquivo XML do VirtualBox no diretório do usuário
    *
    * @param enable
    */
    public static void enableVirtualBoxXmlFile(boolean enable){

        String originalFilePath = System.getProperty("user.home") + File.separator + ".VirtualBox"+File.separator+"VirtualBox.xml";
        String prevFilePath     = System.getProperty("user.home") + File.separator + ".VirtualBox"+File.separator+"VirtualBox.xml-prev";
        String backupFilePath   = System.getProperty("user.home") + File.separator + ".VirtualBox"+File.separator+"VirtualBox.xml_backup";
        String copyFilePath         = Configuration.getInstance().getVmPath() + File.separator+"VirtualBox.xml";


        File originalFile       = new File(originalFilePath);
        File backupFile         = new File(backupFilePath);
        File copyFile           = new File(copyFilePath);


        //Se for para habilitar o arquivo xml padrão do virtualbox, deleta o existente e volta o backup
        if(enable){
//            (new File(prevFilePath)).delete();
            refreshVirtualBoxXml(originalFile, false);
            originalFile.renameTo(copyFile);
            //originalFile.delete();
//            (new File(prevFilePath)).delete();
            backupFile.renameTo(originalFile);
            //backupFile.delete();
            (new File(prevFilePath)).delete();
        }
        //Se for para desabilitar o arquivo padrão do xml, faz um backup
        else{
//            (new File(prevFilePath)).delete();
            backupFile.delete();
//            (new File(prevFilePath)).delete();
            originalFile.renameTo(backupFile);
            //originalFile.delete();

            if(copyFile.exists()){
                refreshVirtualBoxXml(copyFile, true);
                copyFile.renameTo(originalFile);

            }


            (new File(prevFilePath)).delete();
        }
        originalFile = backupFile = copyFile = null;
        System.gc();
    }

    private static void refreshVirtualBoxXml(File file, boolean replace){


        ArrayList<String> lines = new ArrayList<String>();
        FileInputStream stream = null;
        try {
            String projectPath = Configuration.getInstance().getVmPath();

            //JOptionPane.showMessageDialog(null, projectPath);
            stream = new FileInputStream(file);
            InputStreamReader streamReader = new InputStreamReader(stream);
            BufferedReader reader = new BufferedReader(streamReader);
            
           
            String line = null;
            while ((line = reader.readLine()) != null) {
                
                if (replace) {
                    line = line.replace("PROJECT_PATH", projectPath);
                } else {
                    line = line.replace(projectPath, "PROJECT_PATH");
                }
                lines.add(line);
                        //writer.println(line);
            }
            
            // fechando os objetos de io:
            reader.close();
            streamReader.close();
            stream.close();
            
            FileWriter fileWriter = new FileWriter(file);
            PrintWriter writer = new PrintWriter(fileWriter);

            for(String s : lines){
                writer.println(s);
            }

            writer.close();
            fileWriter.close();

            
        } catch (FileNotFoundException ex) {
            Logger.getLogger(XmlManager.class.getName()).log(Level.SEVERE, null, ex);
        } catch (IOException ex) {
            Logger.getLogger(XmlManager.class.getName()).log(Level.SEVERE, null, ex);
        } finally {
            try {
                stream.close();
            } catch (IOException ex) {
                Logger.getLogger(XmlManager.class.getName()).log(Level.SEVERE, null, ex);
            }
        }
    }
}
 
